﻿using System.ComponentModel;
using System.Reflection;

namespace Smp_NetServer
{
    /// <summary>
    /// 统一的数据注入
    /// </summary>
    public static class ToCHelper
    {
        /// <summary>
        /// 自动注入标记了特性的服务
        /// </summary>
        public static IServiceCollection Injection(this IServiceCollection services)
        {
            // 扫描所有被 Inject 特性标记的类型并注册
            foreach (var type in Assembly.GetExecutingAssembly().GetTypes())
            {
                var injectAttr = type.GetCustomAttribute<InjectAttribute>();
                if (injectAttr != null)
                {
                    var serviceType = type.GetInterfaces().FirstOrDefault() ?? type;
                    switch (injectAttr.Lifecycle)
                    {
                        case Lifecycle.Transient:
                            services.AddTransient(serviceType, type);
                            break;
                        case Lifecycle.Singleton:
                            services.AddSingleton(serviceType, type);
                            break;
                        case Lifecycle.Scoped:
                            services.AddScoped(serviceType, type);
                            break;
                    }
                }
            }

            //// 扫描所有被 KeyedInject 特性标记的类型并注册（需搭配支持键值注册的容器）
            //foreach (var type in Assembly.GetExecutingAssembly().GetTypes())
            //{
            //    var keyedAttr = type.GetCustomAttribute<KeyedInjectAttribute>();
            //    if (keyedAttr != null)
            //    {
            //        // 示例：使用 Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions
            //        // 实际键值注册可能需要第三方容器（如 Autofac）
            //        services.AddTransient(keyedAttr.IService, type); // 此处需要根据具体容器调整
            //    }
            //}

            return services;
        }
    }

    /// <summary>
    /// IOC容器注入特性
    /// </summary>
    [AttributeUsage(AttributeTargets.Class, Inherited = false)]
    public class InjectAttribute : Attribute
    {
        public Lifecycle Lifecycle { get; }

        public InjectAttribute(Lifecycle lifecycle = Lifecycle.Singleton)
        {
            Lifecycle = lifecycle;
        }
    }

    /// <summary>
    /// IOC容器接口注入特性（支持键值注册）
    /// </summary>
    [AttributeUsage(AttributeTargets.Class, Inherited = false)]
    public class KeyedInjectAttribute : Attribute
    {
        public Type ServiceType { get; }
        public string Key { get; }
        public Lifecycle Lifecycle { get; }

        public KeyedInjectAttribute(Type serviceType, string key, Lifecycle lifecycle)
        {
            ServiceType = serviceType;
            Key = key;
            Lifecycle = lifecycle;
        }
    }

    /// <summary>
    /// IOC容器注入的生命周期
    /// </summary>
    public enum Lifecycle
    {
        [Description("每次请求都创建新实例")]
        Transient,

        [Description("只创建一次，并共享实例")]
        Singleton,

        [Description("每次请求都创建新实例，但同一个请求共享一个实例")]
        Scoped
    }
}
